#ifndef COURSE_LIB_H_
#define COURSE_LIB_H

#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <sstream>

#include "Course.h"


using namespace std;

void Add_course(string s, Course l[], int &numberCourse){
    string temp, a_sid, a_room, a_time;
    int a_lid;
    short a_semester;

    int mark = s.find("|");
    a_sid = s.substr(0,mark);

    temp = s.substr(mark+1);
    mark = temp.find("|");
    a_lid = atoi(temp.substr(0,mark).c_str());

    temp = temp.substr(mark+1);
    mark = temp.find("|");
    a_semester = atoi(temp.substr(0,mark).c_str());

    temp = temp.substr(mark+1);
    mark = temp.find("|");
    a_room = temp.substr(0,mark);

    temp = temp.substr(mark+1);
    mark = temp.find("|");
    a_time = temp.substr(0,mark);

    Course Course(a_sid, a_lid, a_semester, a_room, a_time);
    l[numberCourse] = Course;
    numberCourse++;
}

void Read_course(string _file, Course l[], int &numberCourse){
    ifstream fin;
    fin.open(_file.c_str());
    if(!fin.is_open()){
        cout<<"Cannot open file.\n";
        exit(1);
    }else{
        string s = "";
        while (getline(fin, s)){
            Add_course(s, l, numberCourse);
        }
        fin.close();
    }
}

void Get_courses_by_sid_lid(string sid, int lid, Course l[], int numberCourse, Course result[], int &numberCourseResult){
    int i = 0;
	numberCourseResult = 0;

    for (i = 0; i < numberCourse; i++){
        if ((l[i].Get_sid() == sid) && (l[i].Get_lid() == lid)){
            result[numberCourseResult] = l[i];
            numberCourseResult++;
        }
    }
}

void Get_courses_by_semester(short semester, Course l[], int numberCourse, Course result[], int &numberCourseResult){
	int i = 0;
	numberCourseResult = 0;

	for(i; i < numberCourse; i++){
		if (l[i].Get_semester() == semester){
			result[numberCourseResult] = l[i];
			numberCourseResult++;
		}
	}
}

void Check_conflict_room(Course l[], int numberCourse, int &numberConflict){
    int j = 0, k = 0;
	numberConflict = 0;
    string room[100], time[100];

    for (j = 0; j < numberCourse; j++){
        room[j] = l[j].Get_room();
        time[j] = l[j].Get_time();
    }

    for (j = 0; j < numberCourse; j++){
        for (k = j; k < numberCourse; k++){
            if (j != k){
                if ((room[j] == room[k]) && (time[j] == time[k])){
                    char* t = (char*)calloc(100, sizeof(char));

                    sprintf(t, "%s:%d", l[j].Get_sid().c_str(), l[j].Get_lid());
                    string c1(t, sizeof(t));

                    sprintf(t, "%s:%d", l[k].Get_sid().c_str(), l[k].Get_lid());
                    string c2(t, sizeof(t));

                    cout << "Course "<<c1<<" vs. "<<" Course "<<c2<<" have same room!\n";
					numberConflict++;
                }
            }
        }
    }
}

void Check_conflict_lecturer(Course l[], int numberCourse, int &numberConflict){
    int j = 0, k = 0, lec[100];
	numberConflict = 0;
    string time[100];

    for (j=0; j<numberCourse;j++){
        lec[j] = l[j].Get_lid();
        time[j] = l[j].Get_time();
    }

    for (j = 0; j < numberCourse; j++){
        for (k = j; k < numberCourse; k++){
            if (j != k){
                if ((lec[j] == lec[k]) && (time[j] == time[k])){
                    char* t = (char*)calloc(100, sizeof(char));

                    sprintf(t, "%s|%s", l[j].Get_sid().c_str(), l[j].Get_time().c_str());
                    string c1(t, sizeof(t));

                    sprintf(t, "%s|%s", l[k].Get_sid().c_str(), l[k].Get_time().c_str());
                    string c2(t, sizeof(t));

                    cout << "Course "<<c1<<" vs. "<<" Course "<<c2<<" have same lecturer!\n";
					numberConflict++;
                }
            }
        }
    }
}

void Get_time_para(Course c, string &start, string &end, int &day){
	string t, day_temp;

	t = c.Get_time();

	int mark = 0;
	mark = t.find("-");
	start = t.substr(0,mark);

	t = t.substr(mark+1);
	mark = t.find("-");
	end = t.substr(0,mark);

	t = t.substr(mark+1);
	day = atoi(t.c_str());
}

int Get_hour_from_string(string s){
	int mark = s.find(":");
	return atoi(s.substr(0,mark).c_str());
}

int Get_minute_from_string(string s){
	int mark = s.find(":");
	return atoi(s.substr(mark, s.length()).c_str());
}

void swap(Course &a, Course &b){
	Course temp;
	temp = a;
	a = b;
	b = temp;
}

/* void Sort_subjects_by_time(Course l[], int numberCourse){
    int i, check, day, day_l;
    float temp1, temp2;
    string start, end, start_l, end_l;
    Course c;

    i = numberCourse - 2;
	do
	{
		check = 1;
		for(i; i>=0; i--){
			Get_time_para(l[i], start, end, day);
			Get_time_para(l[i+1], start_l, end_l, day_l);
			temp1 = Get_hour_from_string(start) + Get_minute_from_string(start)/60;
			temp2 = Get_hour_from_string(start_l) + Get_minute_from_string(start_l)/60;
			if(day < day_l)
			{
				swap(l[i], l[i+1]);
				i = numberCourse-2;
				check = 0;
				continue;
			}else if (day == day_l)
			{
				if(temp1 < temp2)
				{
					swap(l[i], l[i+1]);
					i = numberCourse-2;
					check = 0;
					continue;
				}
			}
		}
	}while(check = 0);
}
 */
 
void Sort_subjects_by_time(Course l[], int numberCourse){
    int i = 0, check, day, day_l;
    float temp1, temp2;
    string start, end, start_l, end_l;
    Course c;
	
	do{
		check = 1;
		for(i = 0; i<numberCourse-1; i++){
			Get_time_para(l[i], start, end, day);
			Get_time_para(l[i+1], start_l, end_l, day_l);
			temp1 = Get_hour_from_string(start) + Get_minute_from_string(start)/60;
			temp2 = Get_hour_from_string(start_l) + Get_minute_from_string(start_l)/60;
			if(l[i].Get_semester() > l[i+1].Get_semester()){
				swap(l[i], l[i+1]);
				check = 0;
				continue;
			}
			if(l[i].Get_semester() == l[i+1].Get_semester() && day > day_l){
				swap(l[i], l[i+1]);
				check = 0;
				continue;
			}
			if(l[i].Get_semester() == l[i+1].Get_semester() && day == day_l && temp1>temp2){
				swap(l[i], l[i+1]);
				check = 0;
				continue;
			}
		}
	}while(check == 0);
	
}
void Print_timetable(Course c[], int numberCourse, Subject s[], int numberSubject, Lecturer l[], int numberLecturer){
    int i = 0;
	Subject temp_s;
	Lecturer temp_l;
    Sort_subjects_by_time(c, numberCourse);
	cout<<setfill('-')<< setw(40) << "Sem"<<c[0].Get_semester()<<setfill('-')<< setw(40) <<"\n";
    for (i = 0; i < numberCourse; i++){
		if(i!=0 && c[i].Get_semester() != c[i-1].Get_semester()){
			cout<<setfill('-')<< setw(40) << "Sem"<<c[i].Get_semester()<<setfill('-')<< setw(40) <<"\n";
		}
        temp_s = Get_subject_by_id(c[i].Get_sid(), s, numberSubject);
		temp_l = Get_lecturer_by_id(c[i].Get_lid(), l, numberLecturer);
		cout<<setfill(' ')<<setw(4)<<c[i].Get_semester()<< setw(30) << temp_s.Get_sname() << setw(25) <<temp_l.Get_fname()<<setw(6)<<c[i].Get_room()<<setw(15) << c[i].Get_time() <<"\n";
    }
}

#endif // COURSE_LIB_H_
